﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BlackBBS.Enums;
using System.Net.Sockets;
using System.IO;
using BlackBBS.Infrastructure.Logging;
using BlackBBS.Extensions;
using BlackBBS.Infrastructure.Repository;
using System.ComponentModel;
using Newtonsoft.Json;
using System.Xml.Serialization;

namespace BlackBBS.Models.Data
{
    [Serializable]
    public class Session : ModelBase
    {
        [NonSerialized]
        private Socket _socket = null;

        [field: NonSerialized]
        public event PropertyChangedEventHandler PropertyChanged;

        public User User { get; set; }

        [XmlIgnore]
        public Socket Socket
        {
            get
            {
                return this._socket;
            }
            set
            {
                this._socket = value;
            }
        }

        public string UserAddress { get; set; }
        public int UserLevel { get; set; }
        public int Node { get; set; }

        public IList<string> RegisteredMsgAreas { get; set; }
        public string MsgExitedToExtProgramFrom { get; set; }

        #region PropertyChangeEvent Properties
        private Area _currentArea = Area.Unknown;
        /// <summary>
        /// Set the current area the user is viewing
        /// <remarks>Setting this triggers the PropertyChanged event</remarks>
        /// </summary>
        public Area CurrentArea
        {
            get
            {
                return this._currentArea;
            }
            set
            {
                this._currentArea = value;
                this.OnPropertyChanged("CurrentArea");
            }
        }
        private string _currentFileArea = null;
        public string CurrentFileArea
        {
            get
            {
                return this._currentFileArea;
            }
            set
            {
                this._currentFileArea = value;
                this.OnPropertyChanged("CurrentFileArea");
            }
        }
        private string _currentMsgArea = null;
        public string CurrentMsgArea
        {
            get
            {
                return this._currentMsgArea;
            }
            set
            {
                this._currentMsgArea = value;
                this.OnPropertyChanged("CurrentMsgArea");
            }
        }
        private string _currentChatRoom = null;
        public string CurrentChatRoom
        {
            get
            {
                return this._currentChatRoom;
            }
            set
            {
                this._currentChatRoom = value;
                this.OnPropertyChanged("CurrentChatRoom");
            }
        }
        #endregion

        public DateTime Expires { get; set; }
        public DateTime Created { get; set; }

        public Session()
        {
            this.Created = DateTime.Now;
        }

        protected void OnPropertyChanged(string name)
        {
            var handler = PropertyChanged;
            if (handler != null && this.User.Id > 0 && this.CurrentArea != Area.Unknown)
            {
                handler(this, new PropertyChangedEventArgs(name));
            }
        }

        public static IList<string> CurrentSessions(IServerRepository serverRepository)
        {
            var results = new List<string>();
            foreach (var session in serverRepository.Sessions.GetAll().OrderBy(x => x.Created))
            {
                var summary = string.Format("Login Time: {0} | User: {1} | Node: {2} | Current Area: {3}",
                                             session.Created.ToString("MM/dd/yyyy HH:mm:ss"),
                                             session.User.Login.PadRight(20),
                                             session.Node.ToString("00"),
                                             session.CurrentArea.ToString().PadRight(30)
                                             );
                results.Add(summary);
            }
            return results;
        }
    }
}
